package com.dl698.util;

import java.io.IOException;

/**
 * 反向字节数组输入流
 * 从字节数组中读取数据
 * 
 * @author wind
 * @version 1.1.1
 */
public class ReverseByteArrayInputStream {

    private byte[] buf;
    private int pos;
    private int mark;
    private int count;

    /**
     * 构造函数
     * 
     * @param buffer 要读取的字节数组
     */
    public ReverseByteArrayInputStream(byte[] buffer) {
        this.buf = buffer;
        this.pos = 0;
        this.count = buffer.length;
        this.mark = 0;
    }

    /**
     * 读取下一个字节
     * 
     * @return 读取的字节值，如果到达流末尾则返回-1
     */
    public int read() {
        return (pos < count) ? (buf[pos++] & 0xff) : -1;
    }

    /**
     * 从流中读取数据到指定的字节数组
     * 
     * @param buf    目标字节数组
     * @param offset 目标数组的起始偏移量
     * @param len    要读取的字节数
     * @return 实际读取的字节数，如果到达流末尾则返回-1
     * @throws IOException 如果参数不合法
     */
    public int readOffset(byte[] buf, int offset, int len) throws IOException {
        if (buf == null) {
            throw new IOException("buf is null");
        }
        if (offset < 0 || len < 0 || len > buf.length - offset) {
            throw new IOException("array index out of bounds");
        }

        if (pos >= count) {
            return -1;
        }

        int avail = count - pos;
        if (len > avail) {
            len = avail;
        }
        if (len <= 0) {
            return 0;
        }

        System.arraycopy(this.buf, pos, buf, offset, len);
        pos += len;
        return len;
    }

    /**
     * 获取可用的字节数
     * 
     * @return 可用的字节数
     */
    public int available() {
        return count - pos;
    }

    /**
     * 标记当前位置
     * 
     * @param readlimit 标记的有效性限制（此实现中忽略此参数）
     */
    public void mark(int readlimit) {
        mark = pos;
    }

    /**
     * 重置到标记位置
     */
    public void reset() {
        pos = mark;
    }

    /**
     * 判断是否支持标记和重置
     * 
     * @return true，此流支持标记和重置
     */
    public boolean markSupported() {
        return true;
    }

    /**
     * 跳过指定数量的字节
     * 
     * @param n 要跳过的字节数
     * @return 实际跳过的字节数
     */
    public long skip(long n) {
        if (n <= 0) {
            return 0;
        }
        long avail = count - pos;
        if (n > avail) {
            n = avail;
        }
        pos += (int) n;
        return n;
    }

    /**
     * 获取当前位置
     * 
     * @return 当前位置
     */
    public int getPos() {
        return pos;
    }

    /**
     * 获取缓冲区
     * 
     * @return 缓冲区数组
     */
    public byte[] getBuf() {
        return buf;
    }

    /**
     * 获取缓冲区长度
     * 
     * @return 缓冲区长度
     */
    public int getCount() {
        return count;
    }
}